import os
from flask import Blueprint, render_template, redirect, url_for, flash, request, current_app, send_from_directory
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename
from app import db
from app.models.post import Post
from app.models.tag import Tag
from app.models.comment import Comment
from app.models.upload import Upload
from app.forms.admin import PostForm, TagForm, UploadForm
from app.utils.decorators import admin_required
import re
from datetime import datetime

def allowed_file(filename):
    # 允许所有文件类型
    return True

admin_bp = Blueprint('admin', __name__)

@admin_bp.before_request
@login_required
@admin_required
def before_request():
    """确保只有管理员可以访问管理页面"""
    pass

@admin_bp.route('/')
def index():
    posts_count = Post.query.count()
    comments_count = Comment.query.count()
    tags_count = Tag.query.count()
    uploads_dir = os.path.join(current_app.root_path, 'static/uploads')
    uploads_count = len(os.listdir(uploads_dir)) if os.path.exists(uploads_dir) else 0
    return render_template('admin/index.html', 
                          posts_count=posts_count,
                          comments_count=comments_count,
                          tags_count=tags_count,
                          uploads_count=uploads_count)

@admin_bp.route('/posts')
def posts():
    page = request.args.get('page', 1, type=int)
    posts = Post.query.order_by(Post.created.desc()).paginate(
        page=page, per_page=current_app.config['POSTS_PER_PAGE'], error_out=False)
    return render_template('admin/posts.html', posts=posts)

@admin_bp.route('/post/new', methods=['GET', 'POST'])
def new_post():
    form = PostForm()
    if form.validate_on_submit():
        # 生成slug
        slug = re.sub(r'[^\w]+', '-', form.title.data.lower())
        post = Post(
            title=form.title.data,
            slug=slug,
            body=form.body.data,
            author=current_user,
            published=form.published.data
        )
        
        # 处理标签
        for tag_name in form.tags.data.split(','):
            tag_name = tag_name.strip()
            if tag_name:
                tag = Tag.query.filter_by(name=tag_name).first()
                if not tag:
                    tag_slug = re.sub(r'[^\w]+', '-', tag_name.lower())
                    tag = Tag(name=tag_name, slug=tag_slug)
                    db.session.add(tag)
                post.tags.append(tag)
        
        db.session.add(post)
        db.session.commit()
        flash('文章已创建')
        return redirect(url_for('admin.posts'))
    
    return render_template('admin/edit_post.html', form=form, title='新建文章')

@admin_bp.route('/post/edit/<int:id>', methods=['GET', 'POST'])
def edit_post(id):
    post = Post.query.get_or_404(id)
    form = PostForm()
    
    if form.validate_on_submit():
        post.title = form.title.data
        post.body = form.body.data
        post.published = form.published.data
        post.on_body_changed()
        post.updated = datetime.utcnow()
        
        # 清除现有标签
        post.tags.clear()
        
        # 处理标签
        for tag_name in form.tags.data.split(','):
            tag_name = tag_name.strip()
            if tag_name:
                tag = Tag.query.filter_by(name=tag_name).first()
                if not tag:
                    tag_slug = re.sub(r'[^\w]+', '-', tag_name.lower())
                    tag = Tag(name=tag_name, slug=tag_slug)
                    db.session.add(tag)
                post.tags.append(tag)
        
        db.session.commit()
        flash('文章已更新')
        return redirect(url_for('admin.posts'))
    
    elif request.method == 'GET':
        form.title.data = post.title
        form.body.data = post.body
        form.published.data = post.published
        form.tags.data = ', '.join([tag.name for tag in post.tags])
    
    return render_template('admin/edit_post.html', form=form, title='编辑文章')

@admin_bp.route('/post/delete/<int:id>', methods=['POST'])
def delete_post(id):
    post = Post.query.get_or_404(id)
    db.session.delete(post)
    db.session.commit()
    flash('文章已删除')
    return redirect(url_for('admin.posts'))

@admin_bp.route('/comments')
def comments():
    page = request.args.get('page', 1, type=int)
    comments = Comment.query.order_by(Comment.created.desc()).paginate(
        page=page, per_page=current_app.config['POSTS_PER_PAGE'], error_out=False)
    return render_template('admin/comments.html', comments=comments)

@admin_bp.route('/comment/approve/<int:id>', methods=['POST'])
def approve_comment(id):
    comment = Comment.query.get_or_404(id)
    comment.approved = True
    db.session.commit()
    flash('评论已批准')
    return redirect(url_for('admin.comments'))

@admin_bp.route('/comment/delete/<int:id>', methods=['POST'])
def delete_comment(id):
    comment = Comment.query.get_or_404(id)
    db.session.delete(comment)
    db.session.commit()
    flash('评论已删除')
    return redirect(url_for('admin.comments'))

@admin_bp.route('/tags')
def tags():
    tags = Tag.query.all()
    return render_template('admin/tags.html', tags=tags)

@admin_bp.route('/tag/new', methods=['GET', 'POST'])
def new_tag():
    form = TagForm()
    if form.validate_on_submit():
        slug = re.sub(r'[^\w]+', '-', form.name.data.lower())
        tag = Tag(name=form.name.data, slug=slug)
        db.session.add(tag)
        db.session.commit()
        flash('标签已创建')
        return redirect(url_for('admin.tags'))
    
    return render_template('admin/edit_tag.html', form=form, title='新建标签')

@admin_bp.route('/tag/edit/<int:id>', methods=['GET', 'POST'])
def edit_tag(id):
    tag = Tag.query.get_or_404(id)
    form = TagForm()
    
    if form.validate_on_submit():
        tag.name = form.name.data
        tag.slug = re.sub(r'[^\w]+', '-', form.name.data.lower())
        db.session.commit()
        flash('标签已更新')
        return redirect(url_for('admin.tags'))
    
    elif request.method == 'GET':
        form.name.data = tag.name
    
    return render_template('admin/edit_tag.html', form=form, title='编辑标签')

@admin_bp.route('/tag/delete/<int:id>', methods=['POST'])
def delete_tag(id):
    tag = Tag.query.get_or_404(id)
    db.session.delete(tag)
    db.session.commit()
    flash('标签已删除')
    return redirect(url_for('admin.tags'))

@admin_bp.route('/uploads', methods=['GET', 'POST'])
def uploads():
    form = UploadForm()
    uploads_dir = os.path.join(current_app.root_path, 'static/uploads')
    os.makedirs(uploads_dir, exist_ok=True)
    
    if form.validate_on_submit():
        file = form.file.data
        if file:
            original_filename = file.filename
            # Save to DB first to get ID
            upload = Upload(
                original_filename=original_filename,
                mimetype=file.mimetype
            )
            db.session.add(upload)
            db.session.flush() # Get ID
            
            # Generate stored filename
            ext = os.path.splitext(original_filename)[1].lower()
            stored_filename = f"F0X{upload.id:03d}{ext}"
            upload.filename = stored_filename
            
            # Save file
            file.save(os.path.join(uploads_dir, stored_filename))
            upload.size = os.path.getsize(os.path.join(uploads_dir, stored_filename))
            
            db.session.commit()
            flash('文件上传成功')
            return redirect(url_for('admin.uploads'))
            
    # Fetch uploads from DB
    all_uploads = Upload.query.order_by(Upload.created_at.desc()).all()
    
    # Mark images for display
    image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp'}
    files_list = []
    for upload in all_uploads:
        ext = os.path.splitext(upload.filename)[1].lower()
        files_list.append({
            'id': upload.id,
            'name': upload.filename,
            'original_name': upload.original_filename,
            'is_image': ext in image_extensions
        })

    return render_template('admin/uploads.html', form=form, uploads=files_list)

@admin_bp.route('/uploads/delete/<int:id>', methods=['POST'])
def delete_upload(id):
    upload = Upload.query.get_or_404(id)
    uploads_dir = os.path.join(current_app.root_path, 'static/uploads')
    filepath = os.path.join(uploads_dir, upload.filename)
    
    if os.path.exists(filepath):
        os.remove(filepath)
        
    db.session.delete(upload)
    db.session.commit()
    flash('文件已删除')
    return redirect(url_for('admin.uploads'))

@admin_bp.route('/uploads/download/<int:id>')
def download_upload(id):
    upload = Upload.query.get_or_404(id)
    uploads_dir = os.path.join(current_app.root_path, 'static/uploads')
    return send_from_directory(
        uploads_dir, 
        upload.filename, 
        as_attachment=True, 
        download_name=upload.original_filename
    )